﻿using WH.Repositories.BaseRepositories;
using Rw.Core.Common.Paging;
using Rw.Core.ORM.Domain;
using WH.Common.Paging;
using System.Linq.Expressions;

namespace WH.Services.BaseService
{
    /// <summary>
    /// 基础服务类
    /// </summary>
    /// <typeparam name="TAggregateRoot"></typeparam>
    public abstract class BaseService<TAggregateRoot> : IBaseService<TAggregateRoot> where TAggregateRoot : class, IAggregateRoot<string>
    {
        private readonly IBaseRepository<TAggregateRoot> _baseRepositories;
        public BaseService(IBaseRepository<TAggregateRoot> baseRepository)
        {
            _baseRepositories = baseRepository;
        }

        public virtual async Task<bool> AnyAsync()
        {
            return await _baseRepositories.AnyAsync();
        }

        public virtual async Task<bool> AnyAsync(Expression<Func<TAggregateRoot, bool>> predicate)
        {
            return await _baseRepositories.AnyAsync(predicate);
        }

        public virtual async Task<int> CountAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null)
        {
            return await _baseRepositories.CountAsync(predicate);
        }

        public virtual async Task<int> CreateAsync(TAggregateRoot entity)
        {
            return await _baseRepositories.CreateAsync(entity);
        }

        public virtual async Task<int> CreateAsync(IEnumerable<TAggregateRoot> entities)
        {
            return await _baseRepositories.CreateAsync(entities);
        }

        public virtual async Task<bool> ExistsAsync(string key)
        {
            return await _baseRepositories.ExistsAsync(key);
        }

        public virtual async Task<bool> ExistsAsync(Expression<Func<TAggregateRoot, bool>> predicate)
        {
            return await _baseRepositories.ExistsAsync(predicate);
        }

        public virtual async Task<IEnumerable<TAggregateRoot>> FindAllAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false)
        {
            return await _baseRepositories.FindAllAsync(predicate, withCache);
        }

        public virtual async Task<TAggregateRoot> FindByIdAsync(string key, bool withCache = false)
        {
            return await _baseRepositories.FindByIdAsync(key, withCache);
        }

        public virtual async Task<TAggregateRoot> FirstOrDefaultAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false)
        {
            return await _baseRepositories.FirstOrDefaultAsync(predicate, withCache);
        }

        public virtual async Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false)
        {
            return await _baseRepositories.PagedFindAllAsync(orderByKeySelector, orderByType, pager, withCache);
        }

        public virtual async Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, bool>> predicate, Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false)
        {
            return await _baseRepositories.PagedFindAllAsync(predicate, orderByKeySelector, orderByType, pager, withCache);
        }

        public virtual async Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, bool>> predicate, PageParam pager, bool withCache = false)
        {
            return await _baseRepositories.PagedFindAllAsync(predicate, pager, withCache);
        }

        public virtual async Task<int> RemoveAsync(TAggregateRoot entity)
        {
            return await _baseRepositories.RemoveAsync(entity);
        }

        public virtual async Task<int> RemoveAsync(IEnumerable<TAggregateRoot> entities)
        {
            return await _baseRepositories.RemoveAsync(entities);
        }

        public virtual async Task<int> RemoveAsync(Expression<Func<TAggregateRoot, bool>> predicate)
        {
            return await _baseRepositories.RemoveAsync(predicate);
        }

        public virtual async Task<int> RemoveByIdAsync(string key)
        {
            return await _baseRepositories.RemoveByIdAsync(key);
        }

        public virtual async Task<int> SaveAsync(TAggregateRoot entity)
        {
            return await _baseRepositories.SaveAsync(entity);
        }

        public virtual async Task<int> SaveAsync(IEnumerable<TAggregateRoot> entities)
        {
            return await _baseRepositories.SaveAsync(entities);
        }

        public virtual async Task<int> UpdateAsync(TAggregateRoot entity)
        {
            return await _baseRepositories.UpdateAsync(entity);
        }

        public virtual async Task<int> UpdateAsync(IEnumerable<TAggregateRoot> entities)
        {
            return await _baseRepositories.UpdateAsync(entities);
        }

        public virtual async Task<int> UpdateColumnsAsync(TAggregateRoot entity, Expression<Func<TAggregateRoot, object>> columns)
        {
            return await _baseRepositories.UpdateColumnsAsync(entity, columns);
        }

        //public async Task<IEnumerable<TAggregateRoot>> FindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false)
        //{
        //    var baseRepositories = _baseRepositories as IBaseOrgContextRepository<TAggregateRoot, TAggregateRoot>;

        //    if (baseRepositories is null)
        //    {
        //        throw new NotImplementedException();
        //    }

        //    return await baseRepositories.FindAllWithOrgContextAsync(predicate, withCache);
        //}


        //public async Task<IPagedList<TAggregateRoot>> PagedFindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>> predicate, Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false)
        //{
        //    var baseRepositories = _baseRepositories as IBaseOrgContextRepository<TAggregateRoot, TAggregateRoot>;

        //    if (baseRepositories is null)
        //    {
        //        throw new NotImplementedException();
        //    }

        //    return await baseRepositories.PagedFindAllWithOrgContextAsync(predicate, orderByKeySelector, orderByType, pager, withCache);
        //}
    }

}

//public class BaseAuditableServices<TAggregateRoot> : IBaseAuditableServices<TAggregateRoot> where TAggregateRoot : class, TAggregateRoot, IAuditable
//{
//    private readonly IBaseAuditableRepositories<TAggregateRoot> _baseAuditableRepositories;
//    public BaseAuditableServices(IBaseAuditableRepositories<TAggregateRoot> baseAuditableRepositories)
//    {
//        _baseAuditableRepositories = baseAuditableRepositories;
//    }
//    public async Task<int> CreateAsync(TAggregateRoot entity)
//    {
//        return await _baseAuditableRepositories.CreateAsync(entity);
//    }

//    public async Task<int> CreateAsync(IEnumerable<TAggregateRoot> entities)
//    {
//        return await _baseAuditableRepositories.CreateAsync(entities);
//    }

//    public async Task<int> SaveAsync(TAggregateRoot entity)
//    {
//        return await _baseAuditableRepositories.SaveAsync(entity);
//    }

//    public async Task<int> SaveAsync(IEnumerable<TAggregateRoot> entities)
//    {
//        return await _baseAuditableRepositories.SaveAsync(entities);
//    }

//    public async Task<int> UpdateAsync(TAggregateRoot entity)
//    {
//        return await _baseAuditableRepositories.UpdateAsync(entity);
//    }

//    public async Task<int> UpdateAsync(IEnumerable<TAggregateRoot> entities)
//    {
//        return await _baseAuditableRepositories.UpdateAsync(entities);
//    }
//}

//public class BaseOrgContextServices<TAggregateRoot> : IBaseOrgContextServices<TAggregateRoot> where TAggregateRoot : class, IOrgAggregateRoot<string>
//{
//    private readonly IBaseOrgContextRepositories<TAggregateRoot> _baseOrgContextRepositories;

//    public BaseOrgContextServices(IBaseOrgContextRepositories<TAggregateRoot> baseOrgContextRepositories)
//    {
//        _baseOrgContextRepositories = baseOrgContextRepositories;
//    }

//    public async Task<IEnumerable<TAggregateRoot>> FindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false)
//    {
//        return await _baseOrgContextRepositories.FindAllWithOrgContextAsync(predicate, withCache);
//    }

//    public async Task<IPagedList<TAggregateRoot>> PagedFindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>> predicate, Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false)
//    {
//        return await _baseOrgContextRepositories.PagedFindAllWithOrgContextAsync(predicate, orderByKeySelector, orderByType, pager, withCache);
//    }
//    }
//}
